package com.writing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.writing.entity.Chapter;
import com.writing.entity.Novel;
import com.writing.mapper.NovelMapper;
import com.writing.service.ChapterService;
import com.writing.service.ChapterSplitService;
import com.writing.service.FileUploadService;
import com.writing.service.NovelService;
import com.writing.util.EncodingDetector;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 小说服务实现类
 */
@Service
@RequiredArgsConstructor
public class NovelServiceImpl extends ServiceImpl<NovelMapper, Novel> implements NovelService {

    private final ChapterService chapterService;
    private final FileUploadService fileUploadService;
    private final ChapterSplitService chapterSplitService;
    
    @Override
    public IPage<Novel> getUserNovels(Long userId, int current, int size) {
        Page<Novel> page = new Page<>(current, size);
        return this.page(page, new LambdaQueryWrapper<Novel>()
                .eq(Novel::getUserId, userId)
                .orderByDesc(Novel::getUpdatedAt));
    }
    
    @Override
    public List<Novel> getUserNovelList(Long userId) {
        return this.list(new LambdaQueryWrapper<Novel>()
                .eq(Novel::getUserId, userId)
                .orderByDesc(Novel::getUpdatedAt));
    }
    
    @Override
    public Novel createNovel(Long userId, Novel novel) {
        novel.setUserId(userId);
        novel.setWordCount(0);
        novel.setChapterCount(0);
        if (novel.getStatus() == null) {
            novel.setStatus("writing");
        }
        this.save(novel);
        return novel;
    }
    
    @Override
    public Novel updateNovel(Long userId, Novel novel) {
        Novel existingNovel = getNovelDetail(userId, novel.getId());
        if (existingNovel == null) {
            throw new RuntimeException("小说不存在");
        }

        // 如果封面发生变化，删除旧的封面文件
        String oldCover = existingNovel.getCover();
        String newCover = novel.getCover();
        if (oldCover != null && !oldCover.equals(newCover)) {
            try {
                fileUploadService.deleteFile(oldCover);
            } catch (Exception e) {
                // 删除失败不影响更新操作，只记录日志
                System.err.println("删除旧封面文件失败: " + oldCover + ", 错误: " + e.getMessage());
            }
        }

        novel.setUserId(userId);
        this.updateById(novel);
        return novel;
    }
    
    @Override
    public boolean deleteNovel(Long userId, Long novelId) {
        Novel novel = getNovelDetail(userId, novelId);
        if (novel == null) {
            throw new RuntimeException("小说不存在");
        }

        // 删除封面文件
        if (novel.getCover() != null) {
            try {
                fileUploadService.deleteFile(novel.getCover());
            } catch (Exception e) {
                // 删除失败不影响删除操作，只记录日志
                System.err.println("删除封面文件失败: " + novel.getCover() + ", 错误: " + e.getMessage());
            }
        }

        return this.removeById(novelId);
    }
    
    @Override
    public Novel getNovelDetail(Long userId, Long novelId) {
        return this.getOne(new LambdaQueryWrapper<Novel>()
                .eq(Novel::getId, novelId)
                .eq(Novel::getUserId, userId));
    }
    
    @Override
    public void updateWordCount(Long novelId) {
        List<Chapter> chapters = chapterService.getChaptersByNovelId(novelId);
        int totalWordCount = chapters.stream()
                .mapToInt(chapter -> chapter.getWordCount() != null ? chapter.getWordCount() : 0)
                .sum();

        Novel novel = new Novel();
        novel.setId(novelId);
        novel.setWordCount(totalWordCount);
        novel.setChapterCount(chapters.size());
        this.updateById(novel);
    }

    @Override
    public Novel uploadNovel(Long userId, MultipartFile file, String title, String genre,
                           String encoding, Boolean autoSplit, String description) {
        // 验证文件
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("文件不能为空");
        }

        if (!file.getOriginalFilename().toLowerCase().endsWith(".txt")) {
            throw new RuntimeException("只支持txt格式的文件");
        }

        // 验证文件大小 (50MB)
        if (file.getSize() > 50 * 1024 * 1024) {
            throw new RuntimeException("文件大小不能超过50MB");
        }

        try {
            // 创建小说记录
            Novel novel = new Novel();
            novel.setUserId(userId);
            novel.setTitle(title);
            novel.setGenre(genre);
            novel.setDescription(description);
            novel.setStatus("writing");
            novel.setWordCount(0);
            novel.setChapterCount(0);
            novel.setProcessingStatus(autoSplit ? "processing" : "completed");

            this.save(novel);

            if (autoSplit) {
                // 先读取文件内容，然后异步处理章节拆分
                String content = readFileContent(file, encoding);
                chapterSplitService.splitChaptersAsync(novel.getId(), content);
            } else {
                // 不拆分，直接作为单个章节保存
                String content = readFileContent(file, encoding);

                Chapter chapter = new Chapter();
                chapter.setNovelId(novel.getId());
                chapter.setChapterOrder(1);
                chapter.setTitle(title);
                chapter.setContent(content);
                chapter.setWordCount(calculateWordCount(content));

                chapterService.createChapter(chapter);

                // 更新小说统计
                novel.setChapterCount(1);
                novel.setWordCount(chapter.getWordCount());
                this.updateById(novel);
            }

            return novel;

        } catch (Exception e) {
            throw new RuntimeException("上传小说失败: " + e.getMessage(), e);
        }
    }

    /**
     * 读取文件内容 - 增强编码检测
     */
    private String readFileContent(MultipartFile file, String encoding) throws Exception {
        // 首先读取文件的前几个字节来检测编码
        byte[] bytes = file.getBytes();

        // 如果文件为空，直接返回
        if (bytes.length == 0) {
            return "";
        }

        String detectedEncoding;

        // 如果用户选择自动检测或者指定的编码无效，使用智能检测
        if ("auto".equals(encoding) || !EncodingDetector.isEncodingSupported(encoding)) {
            detectedEncoding = EncodingDetector.detectEncoding(bytes);

        } else {
            // 验证用户指定的编码是否正确
            try {
                String testContent = new String(bytes, encoding);
                if (!containsGarbledText(testContent)) {
                    detectedEncoding = encoding;

                } else {

                    detectedEncoding = EncodingDetector.detectEncoding(bytes);
                }
            } catch (Exception e) {

                detectedEncoding = EncodingDetector.detectEncoding(bytes);
            }
        }

        try {
            // 使用检测到的编码读取文件
            String content = new String(bytes, detectedEncoding);

            return content;
        } catch (Exception e) {
            // 最后的备用方案
            log.error("使用检测到的编码 {} 读取文件失败，使用UTF-8强制读取: {}");
            return new String(bytes, "UTF-8");
        }
    }



    /**
     * 检查文本是否包含乱码
     */
    private boolean containsGarbledText(String content) {
        if (content == null || content.isEmpty()) {
            return false;
        }

        // 检查是否包含大量的替换字符（�）
        long replacementCharCount = content.chars().filter(ch -> ch == 0xFFFD).count();
        if (replacementCharCount > content.length() * 0.1) { // 如果替换字符超过10%
            return true;
        }

        // 检查是否包含过多的控制字符
        long controlCharCount = content.chars()
                .filter(ch -> Character.isISOControl(ch) && ch != '\n' && ch != '\r' && ch != '\t')
                .count();
        if (controlCharCount > content.length() * 0.05) { // 如果控制字符超过5%
            return true;
        }

        // 检查是否有合理的文本内容（包含常见的中文或英文字符）
        long validCharCount = content.chars()
                .filter(ch -> Character.isLetterOrDigit(ch) ||
                             Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS ||
                             Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A ||
                             Character.UnicodeBlock.of(ch) == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B)
                .count();

        // 如果有效字符少于30%，可能是乱码
        return validCharCount < content.length() * 0.3;
    }

    /**
     * 计算字数
     */
    private int calculateWordCount(String content) {
        if (content == null || content.trim().isEmpty()) {
            return 0;
        }

        // 移除空白字符，计算实际字数
        String cleanContent = content.replaceAll("\\s+", "");
        return cleanContent.length();
    }
}
